package momo.app.comms;

import java.util.ListIterator;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicBoolean;

import momo.app.status.StatusManager;
import momo.app.structure.Message;
import momo.app.util.FileOutput;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class Delayer
{
	static private Delayer delayer;
	
	private Log log = LogFactory.getLog(Delayer.class); 
	
	private Vector<Message> msgStorage;
	
	private AtomicBoolean lock;
	
	private Delayer()
	{
		msgStorage = new Vector<Message>();
		lock = new AtomicBoolean(false);
	}
	
	static public Delayer getInstance()
	{
		if ( delayer == null )
			delayer = new Delayer();
		return delayer;
	}
	
	public void storeDelayedMsg(Message msg)
	{
		msgStorage.add(msg);
	}
	
	public boolean isDelayed()
	{
		return lock.get();
	}
	
	public void delayMsgSent()
	{
		lock.compareAndSet(false, true);
	}
	
	public void freeDelay()
	{
		if ( lock.compareAndSet(true, false) )
			resendMsgInStorage();
	}
	
	private void resendMsgInStorage()
	{
		if ( msgStorage.size() > 0 )
		{
			if ( log.isDebugEnabled() )
				log.debug("Trying to resend all delayed msg");
		}
		
		boolean hasMsgSent = false;
		
		if ( StatusManager.getInstance().isRoot() )
		{
			ListIterator<Message> msgIter = msgStorage.listIterator();
			while ( msgIter.hasNext() )
			{
				Message msg = msgIter.next();
				msg.setForwardType(Message.FORWARD_DOWN);
				
				if ( log.isDebugEnabled() )
					log.debug("Resending (DOWN) msg:\n\t ~~~~ " + msg.toString());
				
				CommsManager.getInstance().forwardDown(msg);
				msgIter.remove();
				hasMsgSent = true;
			}
		}else
		{
			ListIterator<Message> msgIter = msgStorage.listIterator();
			while ( msgIter.hasNext() )
			{
				Message msg = msgIter.next();
				msg.setForwardType(Message.FORWARD_UP);
				
				if ( log.isDebugEnabled() )
					log.debug("Resending (UP) msg:\n\t ~~~~ " + msg.toString());
				
				CommsManager.getInstance().forwardUp(msg);
				msgIter.remove();
				hasMsgSent = true;
			}
		}
		
		if ( hasMsgSent )
		{
			if ( log.isDebugEnabled() )
				log.debug("Messages DID resent");
			System.gc();
		}
	}
	
}//end of class Delayer
